import http from '@ohos.net.http';
import { RequestOptions } from './RequestOption';
import { HttpURLConfig } from './HttpURLConfig';
import { ClassConstructor, plainToInstance } from 'class-transformer';
import { BaseResponse } from './BaseResponse';
import PageList from './PageList';
import { ArrayUtils } from '../utils/ArrayUtils';

/**
 * Http请求器
 */
export class HttpCore {

  /**
   * 发送请求
   * @param requestOption
   * @returns Promise
   */
  request<T>(requestOption: RequestOptions, type: ClassConstructor<T>): Promise<BaseResponse<T>> {
    return new Promise<BaseResponse<T>>((resolve, reject) => {
      this.sendRequest(requestOption)
        .then((response) => {
          if (typeof response.result !== 'string') {
            reject(new Error('Invalid data type'));
          } else {
            let jsonObject = JSON.parse(response.result)
            let baseResponse: BaseResponse<T> = new BaseResponse<T>();
            baseResponse.code = jsonObject.code
            baseResponse.msg = jsonObject.msg
            if (jsonObject.code == '200') {
              if (Array.isArray(jsonObject.data)) {
                baseResponse.dataArray = plainToInstance<T, object>(type, jsonObject.data);
              } else {
                baseResponse.data = plainToInstance(type, jsonObject.data);
              }
            } else {
              baseResponse.data = jsonObject.data;
            }
            if (baseResponse) {
              resolve(baseResponse);
            } else {
              reject(new Error('Invalid data type,JSON to T failed'));
            }

          }
        })
        .catch((error) => {
          reject(error);
        });
    });
  }

  requestList<T>(requestOption: RequestOptions, type: ClassConstructor<T>): Promise<BaseResponse<PageList<T>>> {
    return new Promise<BaseResponse<PageList<T>>>((resolve, reject) => {
      this.sendRequest(requestOption)
        .then((response) => {
          if (typeof response.result !== 'string') {
            reject(new Error('Invalid data type'));
          } else {
            let jsonObject = JSON.parse(response.result)
            let baseResponse: BaseResponse<PageList<T>> = new BaseResponse<PageList<T>>();
            baseResponse.code = jsonObject.code
            baseResponse.msg = jsonObject.msg
            if (baseResponse.code == '200') {
              let data = new PageList<T>();
              data.nowPage = jsonObject.data.nowPage ?? 0;
              data.pageSize = jsonObject.data.pageSize ?? 1;
              data.totalSize = jsonObject.data.totalSize ?? 0;
              data.totalPage = jsonObject.data.totalPage ?? 0;
              data.resultCode = jsonObject.data.resultCode;
              data.resultMsg = jsonObject.data.resultMsg;
              if (ArrayUtils.isNoEmpty(jsonObject.data.rootArray)) {
                data.rootArray = plainToInstance<T, object>(type, jsonObject.data.rootArray);
              }
              if (ArrayUtils.isNoEmpty(jsonObject.data.list)) {
                data.list = plainToInstance<T, object>(type, jsonObject.data.list);
              }
              baseResponse.data = data;
            } else {
              baseResponse.data = jsonObject.data;
            }
            if (baseResponse) {
              resolve(baseResponse);
            } else {
              reject(new Error('Invalid data type,JSON to T failed'));
            }

          }
        })
        .catch((error) => {
          reject(error);
        });
    });
  }


  private sendRequest(requestOption: RequestOptions): Promise<http.HttpResponse> {
    // 每一个httpRequest对应一个HTTP请求任务，不可复用
    let httpRequest = http.createHttp();
    let resolveFunction, rejectFunction;
    const resultPromise = new Promise<http.HttpResponse>((resolve, reject) => {
      resolveFunction = resolve;
      rejectFunction = reject;
    });

    if (!this.isValidUrl(requestOption.url)) {
      return Promise.reject(new Error('url格式不合法.'));
    }
    console.info('Http request:' + JSON.stringify(requestOption, null, 2));

    let promise = httpRequest.request(this.appendQueryParams(HttpURLConfig.BASE_URL + requestOption.url, requestOption.queryParams), {
      method: requestOption.method,
      header: {
        'mac': 'A01-on1uvx8HYk/7x4+9N400h3dt3bl/qgEy',
        // 'clientType': 'ANDROID',
        // 'deviceId': 'A01-on1uvx8HYk/7x4+9N400h3dt3bl/qgEy',da
        'deviceMac': 'A01-on1uvx8HYk/7x4+9N400h3dt3bl/qgEy',
        'Content-Type': 'application/json;charset=utf-8',
        // 'appNameType': '1',
        // 'channelFlag': '2',
        'loginChannel': '3',  //登录渠道校验（登录渠道 1-PC 2-IOS 3-ANDROID 4-小程序 5-小程序）
        // 'Connection': 'close',
        // 'version': '3.0',  //重卡区分版本3.0固定传3.0其他不传
        // 'time': '387417004462348593874',
        // 'nonceStr': '234860',
        // 'Content-Length': '152',
        // 'Host': 'sit-apigateway-core.zczy100.com',
        // 'Accept-Encoding': 'gzip',
        // 'User-Agent': 'okhttp/4.9.0',
        // 'currentVersion': '4.600.0'
      },
      extraData: JSON.stringify(requestOption.extraData), // 当使用POST请求时此字段用于传递内容
    });

    promise.then((response) => {
      console.info('Http code:' + response.responseCode);
      console.info('Http header:' + JSON.stringify(response.header, null, 2));
      console.info('Http Result:' + response.result);


      if (http.ResponseCode.OK !== response.responseCode) {
        throw new Error('http responseCode !=200');
      }
      resolveFunction(response);

    }).catch((err) => {
      rejectFunction(err);
    }).finally(() => {
      // 当该请求使用完毕时，调用destroy方法主动销毁。
      httpRequest.destroy();
    })
    return resultPromise;
  }


  private appendQueryParams(url: string, queryParams: Record<string, string>): string {

    //  使用将参数拼接到url上
    return url;
  }

  private isValidUrl(url: string): boolean {

    // 实现URL格式判断
    return true;

  }
}

export const httpCore = new HttpCore();
